<?php

declare(strict_types=1);

namespace AdminBundle\Services;

use Hyperf\Di\Annotation\Inject;
use AdminBundle\Repositories\SystemMenuRepository;
use Core\Common\Container\AdminPermission;
use Hyperf\DbConnection\Db;
use AdminBundle\Services\PermissionsService;
use Hyperf\Cache\Annotation\Cacheable;

/**
 * MenuService
 * 菜单服务
 */
class MenuService 
{
    /**
     * @Inject()
     * @var AdminPermission
     */
    private $adminPermission;

    /**
     * @Inject
     * @var PermissionsService
     */
    public $permissionsService;
    
    /**
     * getList
     * 条件获取菜单列表
     * @param array $where
     * @param array $order
     * @return mixed
     */
    public function getList($where = [], $order = ['sort' => 'ASC'])
    {
        $query = SystemMenuRepository::instance()
        ->select(['system_menu.id', 'system_menu.system_permission_id', 'system_menu.parent_id', 'system_menu.name', 'system_menu.icon', 'system_menu.path', 'system_menu.sort', 'system_menu.status', 'system_menu.parent_id', 'system_permissions.name as permission_name', 'view']);
        $query = $query->leftjoin('system_permissions', 'system_permissions.id', '=', 'system_menu.system_permission_id');
        
        // 循环增加查询条件
        foreach ($where as $k => $v) {
            if ($v || $v != null) {
                $query = $query->where('system_menu.' . $k, $v);
            }
        }
        // 追加排序
        if ($order && is_array($order)) {
            foreach ($order as $k => $v) {
                $query = $query->orderBy('system_menu.' . $k, $v);
            }
        }
        $query = $query->get();
        return $query ? $query->toArray() : [];
    }

    /**
     * getUserMenuList
     * 获取用户权限对应菜单列表
     *
     * @param string $userId
     * @return array
     * 
     * 清除有问题 先加#号不让执行
     * #@Cacheable(prefix="admin_user_menu",ttl=9000,listener="admin-user-menu")
     */
    public function getUserMenuList($userId = '')
    {
        $userPermissions = $this->adminPermission->getUserAllPermissions($userId);
        $menuList = $this->getList();
        foreach ($menuList as $k =>&$v) {
            if (!empty($v['path']) && !is_url($v['path'])) {
                $v['path'] = '/'.ltrim($v['path'],'/');
            }
            if ( $v['system_permission_id'] && $v['permission_name'] && !in_array($v['permission_name'],$userPermissions) ) {
                unset($menuList[$k]);
            }

            $v['meta'] = ['title' => $v['name'], 'icon' => $v['icon']];
            $v['hidden'] = $v['status'] == 1 ? 0 : 1;
            unset($v['icon']);
        }
        unset($v);
        $tree = handleTreeList($menuList);

        foreach ($tree as $k1 => $v1) {
            if ( !(isset($v1['children']) && $v1['children']) ) {
                unset($tree[$k1]);
            }
        }

        $menu = $this->firstMenu();
        if ($tree) {
            $menu =  array_merge($menu,$tree);
        }
        return $menu;
    }


    private function firstMenu() {
        return [
            [
                "parent_id"=> 0,
                "path"=> "/",
                "name"=>"Home",
                "component"=>"Layout",
                "redirect"=>"/dashboard",
                "status"=>1,
                "children"=>
                    [
                        [
                            "path"=>"dashboard",
                            "status"=>1,
                            "meta"=>
                                [
                                    "title"=>"首页",
                                    "icon"=>"dashboard",
                                ],
                            "name"=>"首页",
                            "component"=> "views/dashboard/index"
                        ]
                    ],
                // "alwaysShow"=>true
            ],
        ];
    }

    /**
     * getMenuTreeList
     * 获取树形结构的菜单列表
     * @return array
     */
    public function getMenuTreeList()
    {
        $list = $this->getList();
        foreach ($list as &$v) {
            if (!empty($v['path']) && !is_url($v['path'])) {
                $v['path'] = ltrim($v['path'],'/');
            }
        }

        $tree = handleTreeList2($list);

        return $tree;
    }

    /**
     * getMenuCount
     * 根据条件获取菜单的总数
     * @param array $where
     * @return mixed
     */
    public function getMenuCount($where = [])
    {
        return SystemMenuRepository::instance()->getCount($where);
    }

    /**
     * saveMenu
     * 保存菜单，构造数据，防止注入
     * 不接收数据库字段以外数据
     * @param $inputData
     * @return null
     */
    public function saveMenu($inputData)
    {
        $saveData = [];
        if (isset($inputData['id']) && $inputData['id']){
            $saveData['id'] = $inputData['id'];
        }
        if (!is_url($inputData['path'])) {
            if (!empty($inputData['parent_id'])){
                $saveData['parent_id'] = $inputData['parent_id'];
                $menu = Db::table('system_menu')->where('id',$inputData['parent_id'])->first();
                $saveData['view'] =$menu->view.'/'. $inputData['path'];
            }else {
                $saveData['view'] = $inputData['path'];
            }
        }
        if (isset($inputData['system_permission_id'])){
            $saveData['system_permission_id'] = $inputData['system_permission_id'];
        }
        if (isset($inputData['name']) && $inputData['name']){
            $saveData['name'] = $inputData['name'];
        }
        if (isset($inputData['icon'])){
            $saveData['icon'] = $inputData['icon'];
        }
        if (isset($inputData['sort'])){
            $saveData['sort'] = $inputData['sort'];
        }
        if (isset($inputData['path'])){
            $saveData['path'] = $inputData['path'];
        }
        if (isset($inputData['description'])){
            $saveData['description'] = $inputData['description'];
        }
        if (isset($inputData['additional'])){
            $saveData['additional'] = $inputData['additional'];
        }
        if (isset($inputData['status'])){
            $saveData['status'] = $inputData['status'];
        }
        $id = SystemMenuRepository::instance()->saveData($saveData)['id'];
        // 清除缓存
        clearPrefixCache('admin_user_menu');
        return $id;
    }

    /**
     * getInfo
     * 根据id获取信息
     * @param $id
     */
    public function getInfo($id)
    {
        return SystemMenuRepository::instance()->find($id);
    }

    /**
     * deleteInfo
     * 根据id删除信息
     * @param $id
     * @return mixed
     */
    public function deleteInfo($id)
    {
        $info = SystemMenuRepository::instance()->deleteByIds($id);

        // 清除缓存
        clearPrefixCache('admin_user_menu');
        return $info;
    }

    /**
     * getMenuPermissionList
     * 通过菜单绑定权限id，获取该权限的权限树，转换成数组返回
     * @param $pid 绑定权限id
     * @return array
     */
    public function getMenuPermissionList($pid)
    {
        if (!$pid) {
            return [];
        }

        $arr = $this->permissionsService->getParentIds($pid);
        $arr[] = $pid;
        return $arr;
    }

    /**
     * orderMenu
     * 拖拽排序
     * @param array $ids
     * @return bool
     */
    public function orderMenu($ids = [])
    {
        if (count($ids) <= 1) {
            return true;
        }

        $order = 0; // 排序计数器
        foreach ($ids as $v) {
            $saveData = [
                'id' => $v,
                'order' => $order
            ];
            $this->saveMenu($saveData);
            $order++;
        }

        return true;
    }
}
